#import "XMLNode.h"
#import "XMLLeafNode.h"
#import "XMLInternalNode.h"

@implementation XMLNode

@synthesize parent;
@synthesize children;

- (id)init
{
    if (self = [super init])
    {
        children = [[NSMutableArray alloc] init];
    }
    return self;
}

- (id)initWithParent:(XMLNode *)p
{
    if (self = [self init])
    {
        parent = p;
    }
    return self;
}

- (NSString *)generateXML
{
    NSMutableString *result = [[NSMutableString alloc] init];
    if (parent == nil)
        [result appendString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"];
    for (int i = 0; i < [children count]; ++i)
        [result appendString:[[children objectAtIndex:i] generateXML]];
    return [result autorelease];
}

- (XMLNode *)queryNode:(NSString *)query
{
    NSArray *queryArray = [query componentsSeparatedByString:@"/"];
    return [self queryNode:queryArray queryStartsAt:0
            queryEndsAt:[queryArray count] - 1];
}

- (XMLNode *)queryNode:(NSArray *)query queryStartsAt:(NSInteger)pos
    queryEndsAt:(NSInteger)end
{
    NSString *key = [query objectAtIndex:pos];
    if ([key length] == 0)
    {
        for (int i = 0; i < [children count]; ++i)
            if ([[children objectAtIndex:i] isKindOfClass:[XMLLeafNode class]])
                return [children objectAtIndex:i];
    }
    else
    {
        for (int i = 0; i < [children count]; ++i)
            if ([[children objectAtIndex:i]
                 isKindOfClass:[XMLInternalNode class]]
                && [[[children objectAtIndex:i] key] isEqualToString:key])
            {
                if (pos == end)
                    return [children objectAtIndex:i];
                return [[children objectAtIndex:i] queryNode:query
                        queryStartsAt:pos + 1 queryEndsAt:end];
            }
    }
    return nil;
}

- (NSArray *)queryNodes:(NSString *)query
{
    NSArray *queryArray = [query componentsSeparatedByString:@"/"];
    XMLNode *node = [self queryNode:queryArray queryStartsAt:0
                     queryEndsAt:[queryArray count] - 2];
    if (node == nil)
        return nil;
    NSMutableArray *result = [[NSMutableArray alloc] init];
    NSString *key = [queryArray objectAtIndex:[queryArray count] - 1];
    if ([key length] == 0)
    {
        for (int i = 0; i < [node.children count]; ++i)
            if ([[node.children objectAtIndex:i]
                 isKindOfClass:[XMLLeafNode class]])
                [result addObject:[node.children objectAtIndex:i]];
    }
    else
    {
        for (int i = 0; i < [node.children count]; ++i)
            if ([[node.children objectAtIndex:i]
                 isKindOfClass:[XMLInternalNode class]]
                && [[[node.children objectAtIndex:i] key] isEqualToString:key])
                [result addObject:[node.children objectAtIndex:i]];
    }
    return [result autorelease];
}

- (void)dealloc
{
    [children release];
    [super dealloc];
}

@end
